package hu.ikti.oamadmin.types.entities;

import java.io.Serializable;
import java.util.Date;
import java.util.List;

import javax.persistence.Basic;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.Lob;
import javax.persistence.ManyToMany;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.SequenceGenerator;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;

import org.jboss.seam.annotations.Name;

@Entity
@Name("bundleData")
@Table(name = "BUNDLEDATA")
@SequenceGenerator(sequenceName = "BUNDLEDATA_SEQ", name = "BD_SEQ", allocationSize = 1)
public class BundleData implements Serializable {

	private static final long serialVersionUID = 1L;

	private Long id;
	private String symbolicName;
	private String presentationName;
	private Version version;
	private String url;
	private List<Requirement> requirements;
	private List<Capability> capabilities;
	private Repository repository;

	private String groupId;
	private String artifactId;

	private ByteCode byteCode;
	private Date uploadTime;
	private String manifest;

	private boolean deleted;;

	@Id
	@Column(name = "ID")
	@GeneratedValue(strategy = GenerationType.AUTO, generator = "BD_SEQ")
	public Long getId() {
		return id;
	}

	@Column(name = "SYMBOLIC_NAME", nullable = false, length = 100)
	public String getSymbolicName() {
		return symbolicName;
	}

	@Column(name = "PRESENTATION_NAME", nullable = true, length = 100)
	public String getPresentationName() {
		return presentationName;
	}

	@OneToOne(cascade = CascadeType.ALL)
	@JoinColumn(name = "VERSION_FK")
	public Version getVersion() {
		return version;
	}

	@Column(name = "URL", nullable = false, length = 150)
	public String getUrl() {
		return url;
	}

	@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
	@JoinTable(name = "BUNDLEDATA_REQUIREMENT_RT", joinColumns = { @JoinColumn(name = "BUNDLEDATA_FK", referencedColumnName = "ID") }, inverseJoinColumns = { @JoinColumn(name = "REQUIREMENT_FK", referencedColumnName = "ID") })
	public List<Requirement> getRequirements() {
		return requirements;
	}

	@ManyToMany(cascade = CascadeType.PERSIST, fetch = FetchType.LAZY)
	@JoinTable(name = "BUNDLEDATA_CAPABILITY_RT", joinColumns = { @JoinColumn(name = "BUNDLEDATA_FK", referencedColumnName = "ID") }, inverseJoinColumns = { @JoinColumn(name = "CAPABILITY_FK", referencedColumnName = "ID") })
	public List<Capability> getCapabilities() {
		return capabilities;
	}

	@OneToOne
	@JoinColumn(name = "REPOSITORY_FK")
	public Repository getRepository() {
		return repository;
	}

	@Column(name = "GROUPID", nullable = true, length = 45)
	public String getGroupId() {
		return groupId;
	}

	@Column(name = "ARTIFACTID", nullable = true, length = 45)
	public String getArtifactId() {
		return artifactId;
	}

	@OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
	@JoinColumn(name = "BYTECODE_FK", nullable = false)
	public ByteCode getByteCode() {
		return byteCode;
	}

	@Temporal(TemporalType.TIMESTAMP)
	@Column(name = "UPLOAD_TIME", nullable = false)
	public Date getUploadTime() {
		return uploadTime;
	}

	@Column(name = "MANIFEST", nullable = true)
	@Lob
	@Basic(fetch = FetchType.LAZY)
	public String getManifest() {
		return manifest;
	}

	@Column(name = "DELETED", nullable = false)
	public boolean isDeleted() {
		return deleted;
	}

	public void setId(Long id) {
		this.id = id;
	}

	public void setSymbolicName(String symbolicName) {
		this.symbolicName = symbolicName;
	}

	public void setPresentationName(String presentationName) {
		this.presentationName = presentationName;
	}

	public void setVersion(Version version) {
		this.version = version;
	}

	public void setUrl(String url) {
		this.url = url;
	}

	public void setRequirements(List<Requirement> requirements) {
		this.requirements = requirements;
	}

	public void setCapabilities(List<Capability> capabilities) {
		this.capabilities = capabilities;
	}

	public void setRepository(Repository repository) {
		this.repository = repository;
	}

	public void setGroupId(String groupId) {
		this.groupId = groupId;
	}

	public void setArtifactId(String artifactId) {
		this.artifactId = artifactId;
	}

	public void setByteCode(ByteCode byteCode) {
		this.byteCode = byteCode;
	}

	public void setUploadTime(Date uploadTime) {
		this.uploadTime = uploadTime;
	}

	public void setManifest(String manifest) {
		this.manifest = manifest;
	}

	public void setDeleted(boolean deleted) {
		this.deleted = deleted;
	}

	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result
				+ ((symbolicName == null) ? 0 : symbolicName.hashCode());
		result = prime * result + ((version == null) ? 0 : version.hashCode());
		return result;
	}

	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		BundleData other = (BundleData) obj;
		if (symbolicName == null) {
			if (other.symbolicName != null)
				return false;
		} else if (!symbolicName.equals(other.symbolicName))
			return false;
		if (version == null) {
			if (other.version != null)
				return false;
		} else if (!version.equals(other.version))
			return false;
		return true;
	}

}
